'use strict';

const uidObj = require('uni-id');
const uidPay = require('uni-pay');

const {
	Controller
} = require('uni-cloud-router');
const dbcmd = uniCloud.database().command;
const xlsx = require('node-xlsx');

module.exports = class OrderController extends Controller {
	// 已收货
	//   结算分销订单（测试阶段，实际应为确认收货7天或15天禁止退换货之后结算）
	async received() {
		let response = {
			code: 1,
		};
		const start = new Date().getTime();
		const nowdate = start;

		const {
			order_id,
			state
		} = this.ctx.data;

		const uid = this.ctx.auth.uid;

		let where_obj = {
			is_delete: 0,
			order_id: order_id
		};

		let orderRes = await this.db.collection('wmzmall-order')
			.where(where_obj)
			.field({
				order_actural_paid: true,
				order_id: true,
				is_fxs: true,
				is_settlement: true,
				order_fxs_uid: true,
				order_fxs_amount: true,
				order_fxs_uid2: true,
				order_fxs_amount2: true,
				order_member_name: true,
				order_member_openid: true,
				order_member_headimg: true,
				order_info: true,
				order_goods_cnt: true,
				create_uid: true
			})
			.get();

		if (!(orderRes && orderRes.data && orderRes.data.length == 1)) {
			uniCloud.logger.info(`订单[${order_id}]不存在`);
			response.msg = `订单[${order_id}]不存在`;
			return response;
		}
		const order = orderRes.data[0];

		let orderUpdate = {
			state: state,
			received_time: nowdate,
			last_modify_time: nowdate,
			last_modify_uname: this.ctx.auth.userInfo.username,
			last_modify_uid: uid
		};
		// 分销订单
		if (order.is_fxs == '是' && order.is_settlement == '否') {
			// 上级
			if (order.order_fxs_uid && order.order_fxs_amount) {
				// 1. 分销商可提现金额
				await this.db.collection('wmzmall-distributor').doc(order.order_fxs_uid).update({
					fxs_unsettled_amount: this.db.command.inc(-order.order_fxs_amount),
					fxs_cashout_amount: this.db.command.inc(order.order_fxs_amount),
					version: this.db.command.inc(1),

					last_modify_uid: uid,
					last_modify_uname: this.ctx.auth.userInfo.username,
					last_modify_time: nowdate
				});
				// 2. 分销记录状态 已结算
				await this.db.collection('wmzmall-distributor-record').where({
					fxs_uid: order.order_fxs_uid,
					order_id: order.order_id
				}).update({
					version: this.db.command.inc(1),
					state: '已结算',

					last_modify_uid: uid,
					last_modify_uname: this.ctx.auth.userInfo.username,
					last_modify_time: nowdate
				});

				// 3. 分销操作日志
				await this.db.collection('wmzmall-distributor-log').add({
					fxs_uid: order.order_fxs_uid,
					oper_content: `结算订单[+${order.order_id}]收益`,
					oper_type: '下单收益',
					oper_ip: this.ctx.context.CLIENTIP,
					remark: `下级会员[${order.order_member_name}]下单[+${order.order_fxs_amount / 100}]`,
					version: 1,
					is_delete: 0,
					create_uid: uid,
					create_uname: this.ctx.auth.userInfo.username,
					create_time: nowdate
				});
			}

			// 上上级
			if (order.order_fxs_uid2 && order.order_fxs_amount2) {
				// 1. 分销商可提现金额
				await this.db.collection('wmzmall-distributor').doc(order.order_fxs_uid2).update({
					fxs_unsettled_amount2: this.db.command.inc(-order.order_fxs_amount2),
					fxs_cashout_amount2: this.db.command.inc(order.order_fxs_amount2),
					version: this.db.command.inc(1),

					last_modify_uid: uid,
					last_modify_uname: this.ctx.auth.userInfo.username,
					last_modify_time: nowdate
				});
				// 2. 分销记录状态 已结算
				await this.db.collection('wmzmall-distributor-record').where({
					fxs_uid: order.order_fxs_uid2,
					order_id: order.order_id
				}).update({
					version: this.db.command.inc(1),
					state: '已结算',

					last_modify_uid: uid,
					last_modify_uname: this.ctx.auth.userInfo.username,
					last_modify_time: nowdate
				});

				// 3. 分销操作日志
				await this.db.collection('wmzmall-distributor-log').add({
					fxs_uid: order.order_fxs_uid2,
					oper_content: `结算订单[+${order.order_id}]收益`,
					oper_type: '下单收益',
					oper_ip: this.ctx.context.CLIENTIP,
					remark: `下下级会员[${order.order_member_name}]下单[+${order.order_fxs_amount2 / 100}]`,
					version: 1,
					is_delete: 0,
					create_uid: uid,
					create_uname: this.ctx.auth.userInfo.username,
					create_time: nowdate
				});
			}

			// 4. 分销订单已结算
			orderUpdate.is_settlement = '是';
			orderUpdate.settlement_time = nowdate;
		}

		const orderUpdateRes = await this.db.collection('wmzmall-order')
			.doc(order._id)
			.update(orderUpdate);

		if (orderUpdateRes && orderUpdateRes.updated == 1) {
			const order_log = {
				order_id: order.order_id,
				log_type: '已收货',
				current_state: state,
				prev_state: '待收货',
				ip: this.ctx.context.CLIENTIP,
				is_delete: 0,
				create_uid: uid,
				create_uname: this.ctx.auth.userInfo.username,
				create_time: nowdate
			};
			await this.db.collection('wmzmall-order-log').add(order_log);
		}

		response.datas = orderUpdateRes;

		const end = new Date().getTime();
		console.log(`耗时：${end - start}ms`);
		response.code = 0;
		response.msg = `耗时：${end - start}ms`;
		return response;
	}

	// 同意退款
	async refund() {
		let response = {
			code: 1,
		};
		const start = new Date().getTime();
		const nowdate = start;

		const {
			id,
			order_id,
			rebate, // 单位元
			remark,
			state
		} = this.ctx.data;
		// console.log('this.ctx.data', this.ctx.data);
		const uid = this.ctx.auth.uid;

		let where_obj = {
			is_delete: 0,
			state: '售后中',
			order_id: order_id,
		};

		// 1. 获取订单数据
		let orderRes = await this.db.collection('wmzmall-order')
			.where(where_obj)
			.field({
				order_actural_paid: true,
				order_id: true,
				state: true,
				is_fxs: true,
				is_settlement: true,
				order_fxs_uid: true,
				order_fxs_amount: true,
				order_member_name: true,
				order_member_openid: true,
				order_member_headimg: true,
				order_info: true,
				order_goods_cnt: true,
				out_trade_no: true,
				order_from: true,
				order_pay_way: true,
				create_uid: true,
			})
			.get();

		if (!(orderRes && orderRes.data && orderRes.data.length == 1)) {
			response.msg = `售后订单[${order_id}]不存在`;
			return response;
		}
		const order = orderRes.data[0];

		// 退款金额
		const refundFee = rebate * 100;

		if (order.order_pay_way == '微信支付') {
			const fs = require('fs');
			const path = require('path');

			let wxpayConfig;
			if (order.order_from == 'app') {
				// APP 微信支付
				wxpayConfig = uidObj.config['app-plus']['wxpay'];
			} else if (order.order_from == '微信公众号') {
				// 微信公众号 微信支付
				wxpayConfig = uidObj.config['h5-weixin']['pay'];
			} else {
				// 微信小程序 微信支付
				wxpayConfig = uidObj.config['mp-weixin']['pay'];
			}

			const wxOptions = {
				...wxpayConfig,
				pfx: fs.readFileSync(path.resolve(__dirname, 'cert/wxpay/apiclient_cert.p12')),
				passphrase: 'password'
			}
			const uniWxpayIns = uidPay.initWeixin(wxOptions);
			const refundRes = await uniWxpayIns.refund({
				outTradeNo: order.out_trade_no,
				outRefundNo: order.out_trade_no,
				totalFee: order.order_actural_paid,
				refundFee: refundFee
			});

			if (refundRes.returnCode != 'SUCCESS') {
				response.msg = refundRes.returnMsg;
				return response;
			}
		} else {
			await this.db.collection('wmzmall-member').doc(order.create_uid).update({
				// 退回用户零钱
				member_amount: this.db.command.inc(refundFee)
			});

			await this.db.collection('wmzmall-member-money-log').add({
				order_id: order_id,
				money: refundFee,
				money_fmt: '+' + rebate,
				source: '订单退款',
				type: '退款',
				remark: `订单退款+${rebate}`,
				ip: this.ctx.context.CLIENTIP,
				is_delete: 0,
				create_uid: order.create_uid,
				create_time: nowdate
			});
		}

		// 2. 修改订单数据
		const orderUpdateRes = await this.db.collection('wmzmall-order')
			.doc(order._id)
			.update({
				state: '售后结束',
				order_refund_state: state,
				order_pay_state: state,
				last_modify_time: nowdate,
				last_modify_uname: this.ctx.auth.userInfo.username,
				last_modify_uid: uid
			});

		if (orderUpdateRes && orderUpdateRes.updated == 1) {
			const orderDetailRes = await this.db.collection('wmzmall-order-detail')
				.where({
					order_id: order.order_id
				}).field({
					goods_id: true,
					goods_sku: true,
					goods_num: true
				}).get();
				
			for (var i = 0; i < orderDetailRes.data.length; i++) {
				let x = orderDetailRes.data[i];
				
				// 释放库存
				await this.db.collection('wmzmall-goods').doc(x.goods_id).update({
					stock_num: dbcmd.inc(x.goods_num),
					sale_cnt: dbcmd.inc(-x.goods_num)
				})
				
				// 释放SKU库存
				if(x.goods_sku) {
					await this.db.collection('wmzmall-goods-sku').where({
						goods_id: x.goods_id,
						goods_sku: x.goods_sku
					}).update({
						stock_num: dbcmd.inc(x.goods_num),
						sale_cnt: dbcmd.inc(-x.goods_num)
					})
				}
			}


			// 3. 修改退款申请数据 
			const refundUpdateRes = await this.db.collection('wmzmall-order-refund')
				.doc(id)
				.update({
					state: state,
					remark: remark,
					last_modify_time: nowdate,
					last_modify_uname: this.ctx.auth.userInfo.username,
					last_modify_uid: uid
				});

			// 4. 插入订单日志
			await this.db.collection('wmzmall-order-log').add({
				order_id: order.order_id,
				log_type: '退款处理',
				current_state: '售后结束',
				prev_state: order.state,
				ip: this.ctx.context.CLIENTIP,
				is_delete: 0,
				create_uid: uid,
				create_uname: this.ctx.auth.userInfo.username,
				create_time: nowdate
			});

			// 5. 修改用户消费金额
			const memberRes = await this.db.collection('wmzmall-member').doc(order.create_uid).update({
				member_monetary: this.db.command.inc(-refundFee)
			});
		}

		response.datas = orderUpdateRes;

		const end = new Date().getTime();
		console.log(`耗时：${end - start}ms`);
		response.code = 0;
		response.msg = `耗时：${end - start}ms`;
		return response;
	}

	// 拒绝退款
	async refuse() {
		let response = {
			code: 1,
		};
		const start = new Date().getTime();
		const nowdate = start;

		const {
			id,
			order_id,
			remark,
			state
		} = this.ctx.data;
		// console.log('this.ctx.data', this.ctx.data);
		const uid = this.ctx.auth.uid;

		let where_obj = {
			is_delete: 0,
			state: '售后中',
			order_id: order_id,
		};

		// 1. 获取订单数据
		let orderRes = await this.db.collection('wmzmall-order')
			.where(where_obj)
			.field({
				order_actural_paid: true,
				order_id: true,
				state: true,
				is_fxs: true,
				is_settlement: true,
				order_fxs_uid: true,
				order_fxs_amount: true,
				order_member_name: true,
				order_member_openid: true,
				order_member_headimg: true,
				order_info: true,
				order_goods_cnt: true,
				create_uid: true,
			})
			.get();

		if (!(orderRes && orderRes.data && orderRes.data.length == 1)) {
			response.msg = `售后订单[${order_id}]不存在`;
			return response;
		}
		const order = orderRes.data[0];

		// 2. 修改订单数据
		const orderUpdateRes = await this.db.collection('wmzmall-order')
			.doc(order._id)
			.update({
				state: '售后结束',
				order_refund_state: state,
				order_refund_remark: remark,
				last_modify_time: nowdate,
				last_modify_uname: this.ctx.auth.userInfo.username,
				last_modify_uid: uid
			});

		if (orderUpdateRes && orderUpdateRes.updated == 1) {

			// 3. 修改退款申请数据 
			const refundUpdateRes = await this.db.collection('wmzmall-order-refund')
				.doc(id)
				.update({
					state: state,
					remark: remark,
					last_modify_time: nowdate,
					last_modify_uname: this.ctx.auth.userInfo.username,
					last_modify_uid: uid
				});

			// 4. 插入订单日志
			await this.db.collection('wmzmall-order-log').add({
				order_id: order.order_id,
				log_type: '退款处理',
				current_state: '售后结束',
				prev_state: order.state,
				ip: this.ctx.context.CLIENTIP,
				is_delete: 0,
				create_uid: uid,
				create_uname: this.ctx.auth.userInfo.username,
				create_time: nowdate
			});
		}

		response.datas = orderUpdateRes;

		const end = new Date().getTime();
		console.log(`耗时：${end - start}ms`);
		response.code = 0;
		response.msg = `耗时：${end - start}ms`;
		return response;
	}

	// 导出
	async exports() {
		let response = {
			code: 1,
		};

		const start = new Date().getTime();
		const nowdate = start;

		const {
			ids
		} = this.ctx.data;

		// xlsx 结构
		let xlsxData = [{
			name: 'sheet1',
			data: [
				[
					'订单号',
					'下单人',
					'订单总额',
					'实际付款',
					'订单状态',
					'订单类型',
					'下单人手机号',
					'下单时间',
					'支付方式',
					'收货人',
					'收货人手机号',
					'订单来源',
					'分销',
					'商品ID',
					'商品名称',
					'商品价格',
					'商品数量',
					'商品SKU',
					'商品SKU名称',
					'VIP商品'
				]
			]
		}]

		// 获取订单
		const orderRes = await this.db.collection('wmzmall-order').aggregate().lookup({
			from: 'wmzmall-order-detail',
			localField: 'order_id',
			foreignField: 'order_id',
			as: 'details'
		}).match({
			_id: dbcmd.in(ids)
		}).limit(ids.length).end()

		let utc8date;
		if (orderRes.data.length) {
			const mappings = this.getExportMapping();
			const mappingDetails = this.getExportDetailMapping();
			orderRes.data.forEach(x => {
				let arr = [];
				utc8date = this.toDateUTC8(new Date(x.create_time));
				x.order_total_money = x.order_total_money / 100;
				x.order_actural_paid = x.order_actural_paid / 100;
				x.create_time = this.formatdate(utc8date);
				mappings.forEach(m => {
					arr.push(x[m]);
				})

				x.details.forEach(d => {
					let detailArr = JSON.parse(JSON.stringify(arr));
					mappingDetails.forEach(m => {
						if (m == 'goods_price') {
							d[m] /= 100;
						}
						if (m == 'is_vip') {
							d[m] = d[m] || '否';
						}
						detailArr.push(d[m]);
					})

					xlsxData[0].data.push(detailArr);
				})
			})
		}
		const sheetOptions = {
			'!cols': [{
				// 订单号
				wch: 23
			}, {
				// 下单人
				wch: 14
			}, {
				// 订单总额
				wch: 15
			}, {
				// 实际付款
				wch: 15
			}, {
				// 订单状态
				wch: 12
			}, {
				// 订单类型
				wch: 12
			}, {
				// 下单人手机号
				wch: 14
			}, {
				// 下单时间
				wch: 22
			}, {
				// 支付方式
				wch: 12
			}, {
				// 收货人
				wch: 12
			}, {
				// 收货人手机号
				wch: 16
			}, {
				// 订单来源
				wch: 14
			}, {
				// 分销
				wch: 10
			}, {
				// 商品ID
				wch: 24
			}, {
				// 商品
				wch: 40
			}, {
				// 商品价格
				wch: 10
			}, {
				// 商品数量
				wch: 10
			}, {
				// 商品SKU
				wch: 14
			}, {
				// 商品SKU名称
				wch: 30
			}, {
				// VIP
				wch: 10
			}]
		};

		let buffer = xlsx.build(xlsxData, {
			sheetOptions
		});
		utc8date = this.toDateUTC8(new Date());
		let fileName = '薇云购(' + this.formatdate(utc8date, 'yyyy-MM-dd hh-mm-ss') + ')' //导出文件名

		//上传文件到云存储
		let uploadRes = await uniCloud.uploadFile({
			cloudPath: fileName + '.xlsx',
			fileContent: buffer
		})
		if (uploadRes.fileID) { //上传成功
			//获取临时下载地址
			let getUrlRes = await uniCloud.getTempFileURL({
				fileList: [uploadRes.fileID]
			})
			//获取文件临时下载地址
			if (getUrlRes.fileList.length) {
				response.datas = {
					name: fileName,
					url: getUrlRes.fileList[0].tempFileURL
				};
			} else {
				response.code = 1
				response.msg = '获取文件下载地址失败'
				return response;
			}
		}

		const end = new Date().getTime();
		response.code = 0;
		response.msg = `耗时：${end - start}ms`;
		return response;
	}

	// 导出订单数据结构
	getExportMapping() {
		return ['order_id', 'order_member_name', 'order_total_money', 'order_actural_paid', 'state',
			'order_type', 'order_member_mobile', 'create_time', 'order_pay_way', 'order_consignee',
			'order_consignee_tel', 'order_from', 'is_fxs'
		];
	}
	// 导出订单明细数据结构
	getExportDetailMapping() {
		return ['goods_id', 'goods_name', 'goods_price', 'goods_num', 'goods_sku', 'goods_sku_name', 'is_vip'];
	}

	// 日期格式化，默认为 'yyyy-MM-dd hh:mm:ss'
	formatdate(date, fmt) {
		date = this.toDate(date);

		fmt = fmt || 'yyyy-MM-dd hh:mm:ss'
		let o = {
			"M+": date.getMonth() + 1, //月份
			"d+": date.getDate(), //日
			"h+": date.getHours(), //小时
			"m+": date.getMinutes(), //分
			"s+": date.getSeconds(), //秒
			"q+": Math.floor((date.getMonth() + 3) / 3), //季度
			"S": date.getMilliseconds() //毫秒
		};

		if (/(y+)/.test(fmt))
			fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
		for (let k in o)
			if (new RegExp("(" + k + ")").test(fmt))
				fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[
					k]).length)));
		return fmt;
	}

	// 将日期格式转换为 new Date()
	toDate(date) {
		if (typeof date === 'string') {
			date = date.replace(/\.|\-/g, '/');
		}
		if (typeof date !== 'object') {
			date = new Date(date);
		}

		return date;
	}

	// 将 UTC+0 转换为 UTC+8
	toDateUTC8(date) {
		date = this.toDate(date);
		// 小时 UTC+0 转换为 UTC+8
		date.setHours(date.getHours() + 8);
		return date;
	}

}
